<template>
<div class="products-page">
<el-button type="primary" icon="el-icon-plus" @click="openDialog('add')" style="margin-bottom: 15px;">
新增商品
</el-button>
<el-table :data="pagedGoods" stripe highlight-current-row style="width: 100%;">
<el-table-column prop="id" label="ID" width="60" />
<el-table-column label="图片" width="100">
<template slot-scope="{ row }">
<img :src="row.image" alt="商品图" class="img-thumb" />
</template>
</el-table-column>
<el-table-column prop="name" label="名称" />
<el-table-column prop="price" label="价格 (元)" width="100">
<template slot-scope="{ row }">
¥{{ row.price.toFixed(2) }}
</template>
</el-table-column>
<el-table-column prop="stock" label="库存" width="80" />
<el-table-column label="操作" width="160">
<template slot-scope="{ row }">
<el-button size="mini" @click="onEdit(row)">编辑</el-button>
<el-button size="mini" type="danger" @click="onDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>

<el-pagination
background
layout="prev, pager, next"
:total="list.length"
:page-size="pageSize"
:current-page.sync="page"
@current-change="onPageChange"
style="margin-top: 15px; text-align: right;"
/>

<!-- 新增/编辑 对话框 -->
<el-dialog
:title="dialogMode === 'add' ? '新增商品' : '编辑商品'"
:visible.sync="dialogVisible"
width="400px"
>
<el-form :model="form" label-width="80px">
<el-form-item label="名称">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="价格">
<el-input-number v-model.number="form.price" :min="0" :step="0.1" />
</el-form-item>
<el-form-item label="库存">
<el-input-number v-model.number="form.stock" :min="0" />
</el-form-item>
<el-form-item label="图片URL">
<el-input v-model="form.image" placeholder="必填: assets 下文件名，如 apple.jpg" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="onCancel">取消</el-button>
<el-button type="primary" @click="onSave">保存</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
// 如果你希望自动解析 assets 下图片文件名到 require，可使用下面方法：
export default {
data() {
return {
list: [
{ id: 1, name: '苹果', price: 4.5, stock: 100, image: require('@/assets/apple.jpg') },
{ id: 2, name: '香蕉', price: 3.2, stock: 150, image: require('@/assets/banana.jpg') },
{ id: 3, name: '橙子', price: 5.0, stock: 120, image: require('@/assets/orange.jpg') },
{ id: 4, name: '葡萄', price: 6.8, stock: 80, image: require('@/assets/grape.jpg') },
{ id: 5, name: '西瓜', price: 2.5, stock: 60, image: require('@/assets/watermelon.jpg') },
{ id: 6, name: '菠萝', price: 8.0, stock: 50, image: require('@/assets/pineapple.jpg') },
{ id: 7, name: '草莓', price: 15.0,stock: 40, image: require('@/assets/strawberry.jpg') },
{ id: 8, name: '猕猴桃',price: 9.0, stock: 70, image: require('@/assets/kiwi.jpg') },
{ id: 9, name: '桃子', price: 7.5, stock: 90, image: require('@/assets/peach.jpg') },
{ id: 10,name: '柠檬', price: 4.0, stock: 110, image: require('@/assets/lemon.jpg') },
{ id: 11,name: '樱桃', price: 18.0,stock: 30, image: require('@/assets/cherry.jpg') },
{ id: 12,name: '蓝莓', price: 20.0,stock: 25, image: require('@/assets/blueberry.jpg') },
{ id: 13,name: '杏子', price: 6.0, stock: 80, image: require('@/assets/apricot.jpg') },
{ id: 14,name: '石榴', price: 12.0,stock: 55, image: require('@/assets/pomegranate.jpg') },
{ id: 15,name: '龙眼', price: 14.0,stock: 45, image: require('@/assets/longan.jpg') }
],
page: 1,
pageSize: 6,
dialogVisible: false,
dialogMode: 'add', // 'add' or 'edit'
form: { id: null, name: '', price: 0, stock: 0, image: '' }
}
},
computed: {
pagedGoods() {
const start = (this.page - 1) * this.pageSize
return this.list.slice(start, start + this.pageSize)
}
},
methods: {
onPageChange(p) {
this.page = p
},
onEdit(row) {
this.dialogMode = 'edit'
this.form = { ...row }
this.dialogVisible = true
},
onDelete(id) {
this.$confirm('确认删除该商品？', '提示', { type: 'warning' })
.then(() => {
this.list = this.list.filter(item => item.id !== id)
this.$message.success('删除成功')
})
.catch(() => {})
},
onCancel() {
this.dialogVisible = false
this.resetForm()
},
onSave() {
if (!this.form.name || !this.form.image) {
this.$message.error('请填写名称和图片文件名')
return
}
if (this.dialogMode === 'add') {
const newId = this.list.length ? Math.max(...this.list.map(i => i.id)) + 1 : 1
// image 字段必须像 require('@/assets/xxx.jpg') 或你自行填写完整路径
this.list.push({ ...this.form, id: newId, image: require(`@/assets/${this.form.image}`) })
this.$message.success('新增成功')
} else {
const idx = this.list.findIndex(item => item.id === this.form.id)
if (idx !== -1) {
this.list.splice(idx, 1, {
...this.form,
image: require(`@/assets/${this.form.image}`)
})
this.$message.success('更新成功')
}
}
this.dialogVisible = false
this.resetForm()
},
resetForm() {
this.dialogMode = 'add'
this.form = { id: null, name: '', price: 0, stock: 0, image: '' }
}
}
}
</script>

<style scoped>
.img-thumb {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 4px;
}
.dialog-footer {
text-align: right;
}
</style>